package net.sf.midollo.midlet;

import java.io.IOException;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDletStateChangeException;

import net.sf.midollo.io.lcdui.textbox.TextBoxIOStream;
import net.sf.midollo.io.lcdui.textbox.TextBoxOutputStream;
import net.sf.midollo.midlet.common.BaseMIDlet;
import net.sf.midollo.midlet.common.CommandEvent;
import net.sf.midollo.midlet.common.CommandEventManager;
import net.sf.midollo.midlet.common.ConnectionEditor;
import net.sf.midollo.net.io.StreamConnectionIOStreamFactory;
import net.sf.midollo.net.protocol.tunnel.Tunnel;
import net.sf.midollo.utils.MidpUtils;
import net.sf.midollo.utils.Utils;

public class Telnet extends BaseMIDlet {
  public static final String DEF_CONN = "socket://127.0.0.1:64080";

  protected Command sendCommand;
  protected Command replyCommand;
  protected TextBox requestTextBox;
  protected TextBox responseTextBox;
  protected TextBoxIOStream clientIOStream;
  protected Tunnel tunnel;

  public Telnet() {
    this.commandEventManager = new CommandEventManager();
  }

  public void run() {
    try {
      Form configForm = new Form("Telnet Config");
      ConnectionEditor connEditor = new ConnectionEditor(configForm, DEF_CONN);
      configForm.setCommandListener(this);
      configForm.addCommand(this.okCommand);
      configForm.addCommand(this.exitCommand);
      this.display.setCurrent(configForm);

      CommandEvent commandEvent = new CommandEvent();
      while (true) {
        this.commandEventManager.waitCommand(commandEvent);
        if (commandEvent.equals(this.okCommand, configForm)) {
          this.commandEventManager = null;
          break;
        }
      }

      String connName = connEditor.getValue();

      this.responseTextBox = new TextBox("Response", null, 8000, TextField.UNEDITABLE);
      MidpUtils.LOG_STREAM = new TextBoxOutputStream(this.responseTextBox);
      this.replyCommand = new Command("Reply", Command.OK, 1);
      this.responseTextBox.addCommand(replyCommand);
      this.responseTextBox.addCommand(exitCommand);
      this.responseTextBox.setCommandListener(this);

      this.requestTextBox = new TextBox("Request", null, 8000, 0);
      this.sendCommand = new Command("Send", Command.OK, 1);
      this.requestTextBox.addCommand(sendCommand);
      this.requestTextBox.addCommand(exitCommand);
      this.requestTextBox.setCommandListener(this);

      this.display.setCurrent(this.responseTextBox);

      Utils.log("clientIOStream");
      this.clientIOStream = new TextBoxIOStream(this.requestTextBox, this.responseTextBox);
      Utils.log("serverConnFactory");
      StreamConnectionIOStreamFactory serverConnFactory = new StreamConnectionIOStreamFactory(connName);
      Utils.log("tunnel");
      this.tunnel = new Tunnel(this.clientIOStream, serverConnFactory, 32, 32);
      Utils.log("run");
      this.tunnel.run();
    } catch (Exception ex) {
      MidpUtils.showError(this.display, ex);
    }
  }

  public boolean handleCommandAction(Command c, Displayable d) {
    if (!super.handleCommandAction(c, d)) {
      if (c == sendCommand) {
        this.clientIOStream.acceptInput();
        this.display.setCurrent(this.responseTextBox);
        return true;
      } else if (c == replyCommand) {
        this.display.setCurrent(this.requestTextBox);
        return true;
      }
    }
    return false;
  }

  protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
    if (this.tunnel != null) {
      try {
        this.tunnel.disconnect();
      } catch (IOException ex) {
      }
    }
    super.destroyApp(unconditional);
  }
}
